package com.java1234.common.security;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.java1234.entity.*;
import com.java1234.service.LoginLogService;
import com.java1234.service.SysMenuService;
import com.java1234.service.SysRoleService;
import com.java1234.service.SysUserService;
import com.java1234.util.IpUtil;
import com.java1234.util.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.Authentication;
import org.springframework.security.web.authentication.AuthenticationSuccessHandler;
import org.springframework.stereotype.Component;

import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 登录成功处理器
 */
@Slf4j
@Component
public class LoginSuccessHandler implements AuthenticationSuccessHandler {

    @Autowired
    private SysUserService sysUserService;

    @Autowired
    private SysRoleService sysRoleService;

    @Autowired
    private SysMenuService sysMenuService;

    @Autowired
    private LoginLogService loginLogService;

    @Override
    public void onAuthenticationSuccess(HttpServletRequest httpServletRequest, HttpServletResponse httpServletResponse, Authentication authentication) throws IOException, ServletException {
        httpServletResponse.setContentType("application/json;charset=UTF-8");
        ServletOutputStream outputStream = httpServletResponse.getOutputStream();

        String username = authentication.getName();
        String token = JwtUtils.genJwtToken(username);

        SysUser currentUser = sysUserService.getByUsername(username);

        // 根据用户id获取所有的角色信息
        List<SysRole> roleList = sysRoleService.list(new QueryWrapper<SysRole>().inSql("id", "SELECT role_id FROM sys_user_role WHERE user_id=" + currentUser.getId()));

        // 提取角色ID列表
        List<Long> roleIds = roleList.stream().map(SysRole::getId).collect(Collectors.toList());

        // 遍历所有的角色，获取所有菜单权限 而且不重复
        Set<SysMenu> menuSet = new HashSet<>();
        for (SysRole sysRole : roleList) {
            List<SysMenu> sysMenuList = sysMenuService.list(new QueryWrapper<SysMenu>().inSql("id", "SELECT menu_id FROM sys_role_menu WHERE role_id=" + sysRole.getId()));
            menuSet.addAll(sysMenuList);
        }

        // 将当前用户的所有角色名称提取出来，用逗号分隔，然后设置到当前用户的 roles 属性中
        currentUser.setRoles(roleList.stream().map(SysRole::getName).collect(Collectors.joining(",")));

        List<SysMenu> sysMenuList = new ArrayList<>(menuSet);

        // 排序
        sysMenuList.sort(Comparator.comparing(SysMenu::getOrderNum));

        // 转菜单树
        List<SysMenu> menuList = sysMenuService.buildTreeMenu(sysMenuList);

        // 记录登录日志
        recordLoginLog(httpServletRequest, username, "SUCCESS");

        // 构建响应数据
        Map<String, Object> responseData = new HashMap<>();
        responseData.put("code", 200);
        responseData.put("msg", "登录成功");
        responseData.put("authorization", token);
        responseData.put("currentUser", currentUser);
        responseData.put("menuList", menuList);
        responseData.put("roleIds", roleIds); // 添加角色ID列表

        outputStream.write(JSONUtil.toJsonStr(responseData).getBytes());
        outputStream.flush();
        outputStream.close();
    }

    private void recordLoginLog(HttpServletRequest request, String username, String status) {
        LoginLog loginLog = new LoginLog();
        loginLog.setUsername(username);
        loginLog.setIpAddress(IpUtil.getIpAddr(request));
        loginLog.setLoginTime(new Date());
        loginLog.setStatus(status);
        loginLog.setCreateTime(new Date());
        loginLog.setUpdateTime(new Date());

        loginLogService.logLogin(loginLog);
        log.info("用户 {} 登录成功，IP地址：{}", username, loginLog.getIpAddress());
    }
}